package com.chatdating.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chatdating.config.AliPayConfig;
import com.chatdating.entity.Member;
import com.chatdating.entity.OrderInfo;
import com.chatdating.entity.User;
import com.chatdating.entity.dto.MessageSendDto;
import com.chatdating.entity.dto.SendVip;
import com.chatdating.mapper.OrderInfoMapper;
import com.chatdating.mapper.UserMapper;
import com.chatdating.service.MemberService;
import com.chatdating.service.OrderService;
import com.chatdating.utils.EmptyUtil;
import com.chatdating.websocket.ChannelContextUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.ZoneId;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/alipay")
@RequiredArgsConstructor
public class AliPayController extends ServiceImpl<OrderInfoMapper, OrderInfo> {

    private final AliPayConfig aliPayConfig;
    private final OrderService orderService;

    @Resource
    private ChannelContextUtils channelContextUtils;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MemberService memberService;


    @PostMapping("/notify")
    public String paymentNotify(HttpServletRequest request) {
        log.info("收到支付宝回调请求，Method: {}, ContentType: {}",
                request.getMethod(), request.getContentType());

        Map<String, String> params = convertParamsToMap(request);
        log.info("支付宝回调参数: {}", params);

        try {
            // 1. 验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(
                    params,
                    aliPayConfig.getAlipayPublicKey(),
                    aliPayConfig.getCharset(),
                    aliPayConfig.getSignType()
            );

            if (!signVerified) {
                log.error("支付宝回调签名验证失败, params: {}", params);
                return "failure";
            }

            // 2. 验证通知参数
            String appId = params.get("app_id");
            String tradeStatus = params.get("trade_status");
            String outTradeNo = params.get("out_trade_no");
            String totalAmount = params.get("total_amount");

            // 3. 验证APP_ID是否匹配
            if (!aliPayConfig.getAppId().equals(appId)) {
                log.error("APP_ID不匹配, 配置: {}, 回调: {}", aliPayConfig.getAppId(), appId);
                return "failure";
            }

            // 4. 处理交易状态
            if ("TRADE_SUCCESS".equals(tradeStatus) ||
                    "TRADE_FINISHED".equals(tradeStatus)) {

                // 5. 处理订单支付
                boolean processResult = orderService.processPayment(
                        outTradeNo,
                        totalAmount,
                        params
                );

                if (processResult) {
                    OrderInfo order = getOrderByNo(outTradeNo);
                    Long userId = order.getUserId();
                    User byId = userMapper.findById(Integer.valueOf(userId.toString()));

                    //充值成功，更新member表
                    Member member = new Member();
                    member.setUid(userId);
                    member.setCreateTime(order.getPaymentTime());
                    switch (order.getSubject()) {
                        case "购买月卡会员":
                            member.setEndTime(order.getPaymentTime().plusMonths(1));
                            break;
                        case "购买季卡会员":
                            member.setEndTime(order.getPaymentTime().plusMonths(3));
                            break;
                        case "购买年卡会员":
                            member.setEndTime(order.getPaymentTime().plusYears(1));
                            break;
                    }
                    QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("uid",userId);
                    List<Member> list = memberService.list(queryWrapper);
                    if(EmptyUtil.isNotEmpty(list)){
                        Member member1 = list.get(0);
                        int id = member1.getId();
                        member.setId(id);
                    }
                    memberService.saveOrUpdate(member);

                    //向前端发送消息
                    SendVip sendVip = new SendVip();
                    sendVip.setIsvip(1);
                    ZoneId zone = ZoneId.of("Asia/Shanghai"); // 或 ZoneOffset.UTC
                    sendVip.setEndTime(member.getEndTime().atZone(zone).toInstant().toEpochMilli());
                    MessageSendDto messageSendDto = new MessageSendDto();
                    messageSendDto.setSendVip(sendVip);
                    channelContextUtils.sendMsg(messageSendDto,byId.getUsername());

                    log.info("订单处理成功: {}", outTradeNo);
                    return "success";
                } else {
                    log.error("订单处理失败: {}", outTradeNo);
                }
            } else {
                log.warn("未处理的交易状态: {}, 订单号: {}", tradeStatus, outTradeNo);
            }
        } catch (AlipayApiException e) {
            log.error("支付宝回调验签异常", e);
        } catch (Exception e) {
            log.error("处理支付宝回调异常", e);
        }
        return "failure";
    }

    // 将回调参数转换为Map
    private Map<String, String> convertParamsToMap(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();

        // 获取所有参数名
        Enumeration<String> paramNames = request.getParameterNames();

        while (paramNames.hasMoreElements()) {
            String paramName = paramNames.nextElement();
            String[] values = request.getParameterValues(paramName);

            if (values != null && values.length > 0) {
                // 支付宝回调参数都是单值
                params.put(paramName, values[0]);
                log.debug("回调参数: {} = {}", paramName, values[0]);
            }
        }

        return params;
    }

    public OrderInfo getOrderByNo(String orderNo) {
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        return getOne(queryWrapper);
    }
}